home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 2000 October / Software of the Month - Ultimate Collection Shareware 277.iso / pc / PROGRAMS / UTILITY / WINLINUX / DATA1.CAB / programs_-_include / ASM-SPAR.{_6 / ATOMIC.H < prev    next >
C/C++ Source or Header  |  1999-09-17  |  3KB  |  143 lines

  1. /* atomic.h: These still suck, but the I-cache hit rate is higher.
  2.  *
  3.  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
  4.  */
  5.  
  6. #ifndef __ARCH_SPARC_ATOMIC__
  7. #define __ARCH_SPARC_ATOMIC__
  8.  
  9. #ifdef __SMP__
  10. /* This is a temporary measure. -DaveM */
  11. typedef struct { volatile int counter; } atomic_t;
  12. #define ATOMIC_INIT(i)    { (i << 8) }
  13. #else
  14. typedef struct { int counter; } atomic_t;
  15. #define ATOMIC_INIT(i)  { (i) }
  16. #endif
  17.  
  18. #ifdef __KERNEL__
  19. #include <asm/system.h>
  20. #include <asm/psr.h>
  21.  
  22. #ifndef __SMP__
  23.  
  24. #define atomic_read(v)          ((v)->counter)
  25. #define atomic_set(v, i)        (((v)->counter) = i)
  26.  
  27. #else
  28. /* We do the bulk of the actual work out of line in two common
  29.  * routines in assembler, see arch/sparc/lib/atomic.S for the
  30.  * "fun" details.
  31.  *
  32.  * For SMP the trick is you embed the spin lock byte within
  33.  * the word, use the low byte so signedness is easily retained
  34.  * via a quick arithmetic shift.  It looks like this:
  35.  *
  36.  *    ----------------------------------------
  37.  *    | signed 24-bit counter value |  lock  |  atomic_t
  38.  *    ----------------------------------------
  39.  *     31                          8 7      0
  40.  */
  41.  
  42. static __inline__ int atomic_read(atomic_t *v)
  43. {
  44.     int val;
  45.  
  46.     __asm__ __volatile__("sra    %1, 0x8, %0"
  47.                  : "=r" (val)
  48.                  : "r" (v->counter));
  49.     return val;
  50. }
  51. #define atomic_set(v, i)    (((v)->counter) = ((i) << 8))
  52. #endif
  53.  
  54. /* Make sure gcc doesn't try to be clever and move things around
  55.  * on us. We need to use _exactly_ the address the user gave us,
  56.  * not some alias that contains the same information.
  57.  */
  58. #define __atomic_fool_gcc(x) ((struct { int a[100]; } *)x)
  59.  
  60. static __inline__ void atomic_add(int i, atomic_t *v)
  61. {
  62.     register atomic_t *ptr asm("g1");
  63.     register int increment asm("g2");
  64.     ptr = (atomic_t *) __atomic_fool_gcc(v);
  65.     increment = i;
  66.  
  67.     __asm__ __volatile__("
  68.     mov    %%o7, %%g4
  69.     call    ___atomic_add
  70.      add    %%o7, 8, %%o7
  71. "    : "=&r" (increment)
  72.     : "0" (increment), "r" (ptr)
  73.     : "g3", "g4", "g7", "memory", "cc");
  74. }
  75.  
  76. static __inline__ void atomic_sub(int i, atomic_t *v)
  77. {
  78.     register atomic_t *ptr asm("g1");
  79.     register int increment asm("g2");
  80.  
  81.     ptr = (atomic_t *) __atomic_fool_gcc(v);
  82.     increment = i;
  83.  
  84.     __asm__ __volatile__("
  85.     mov    %%o7, %%g4
  86.     call    ___atomic_sub
  87.      add    %%o7, 8, %%o7
  88. "    : "=&r" (increment)
  89.     : "0" (increment), "r" (ptr)
  90.     : "g3", "g4", "g7", "memory", "cc");
  91. }
  92.  
  93. static __inline__ int atomic_add_return(int i, atomic_t *v)
  94. {
  95.     register atomic_t *ptr asm("g1");
  96.     register int increment asm("g2");
  97.  
  98.     ptr = (atomic_t *) __atomic_fool_gcc(v);
  99.     increment = i;
  100.  
  101.     __asm__ __volatile__("
  102.     mov    %%o7, %%g4
  103.     call    ___atomic_add
  104.      add    %%o7, 8, %%o7
  105. "    : "=&r" (increment)
  106.     : "0" (increment), "r" (ptr)
  107.     : "g3", "g4", "g7", "memory", "cc");
  108.  
  109.     return increment;
  110. }
  111.  
  112. static __inline__ int atomic_sub_return(int i, atomic_t *v)
  113. {
  114.     register atomic_t *ptr asm("g1");
  115.     register int increment asm("g2");
  116.  
  117.     ptr = (atomic_t *) __atomic_fool_gcc(v);
  118.     increment = i;
  119.  
  120.     __asm__ __volatile__("
  121.     mov    %%o7, %%g4
  122.     call    ___atomic_sub
  123.      add    %%o7, 8, %%o7
  124. "    : "=&r" (increment)
  125.     : "0" (increment), "r" (ptr)
  126.     : "g3", "g4", "g7", "memory", "cc");
  127.  
  128.     return increment;
  129. }
  130.  
  131. #define atomic_dec_return(v) atomic_sub_return(1,(v))
  132. #define atomic_inc_return(v) atomic_add_return(1,(v))
  133.  
  134. #define atomic_sub_and_test(i, v) (atomic_sub_return((i), (v)) == 0)
  135. #define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
  136.  
  137. #define atomic_inc(v) atomic_add(1,(v))
  138. #define atomic_dec(v) atomic_sub(1,(v))
  139.  
  140. #endif /* !(__KERNEL__) */
  141.  
  142. #endif /* !(__ARCH_SPARC_ATOMIC__) */
  143.